---
title: 原子类
description: 原子类能够解决一些简单的原子性问题（针对一个共享变量的），如果需要解决多个原子性问题，建议还是使用互斥锁。
---

无锁方案相对于互斥锁方案，最大的好处就是**性能**。互斥锁方案为了保证互斥性，需要执行加锁、解锁操作，而加锁、解锁操作本身就耗费性能；同时拿不到锁的线程还会进入阻塞状态，进而触发线程切换，线程切换对性能的消耗也很大。

相比之下，无锁方案则完全没有加锁、解锁的性能损耗，同时还能保证互斥性。

## 无锁方案的实现原理

原子类性能高的原因很简单，硬件支持而已。

CPU 为了解决并发问题，提供了 CAS 指令（CAS ，全称是 Compare And Swap，即比较并交换）。CAS 指令包含 3 个参数：共享变量的内存地址 A 、用于比较的值 B 和共享变量的新值 C；
并且只有当内存中地址 A 处的值 等于 B 时，才能将内存中地址 A 处的值更新为新值 C。

作为一条 CPU 指令，CAS 指令本身是能够保证原子性的。

使用 CAS 解决并发问题，一般都会伴随着自旋（循环尝试）。尝试读取新值重新执行操作。

使用原子类需要关系 ABA 问题，尤其是原子化的更新对象时更需要关系 ABA 问题，因为两个 A 虽然相等，但是第二个 A 的属性可能已经发生变化了。所以使用需要 check一下。

## 原子类
Java SDK 并发包提供的原子类可以分为五个类别：
**原子化的基本数据类型、原子化的对象引用类型、原子化数组、原子化对象属性更新器和原子化的累加器**

![007a32583fbf519469462fe61805eb4a](https://img.wkq.pub/pic/007a32583fbf519469462fe61805eb4a.webp)

### 1. 原子化的基本类型

相关实现由 AtomicBoolean、AtomicInteger 和 AtomicLong，提供的方法主要有下面这些：

```java

getAndIncrement() //原子化i++
getAndDecrement() //原子化的i--
incrementAndGet() //原子化的++i
decrementAndGet() //原子化的--i
//当前值+=delta，返回+=前的值
getAndAdd(delta) 
//当前值+=delta，返回+=后的值
addAndGet(delta)
//CAS操作，返回是否成功
compareAndSet(expect, update)
//以下四个方法
//新值可以通过传入func函数来计算
getAndUpdate(func)
updateAndGet(func)
getAndAccumulate(x,func)
accumulateAndGet(x,func)
```

### 2. 原子化的对象引用类型

相关实现有 AtomicReference、AtomicStampedReference 和 AtmoicMarkableReference，利用它们可以实现对象引用的原子化更新。AtomicReference 提供的方法和原子化的基本数据类型差不多。

对象引用的更新需要重点关注 ABA 问题，AtomicStampedReference 和 AtomicMarkableReference 这两个原子类可以解决 ABA 问题。

解决 ABA 问题的思路其实很简单， 增加一个版本号维度就可以了，这个和乐观锁机制很类似，每次执行 CAS 操作，附加再更新一个版本号，只要保证版本号是递增的，那么即使  A 变成 B 又变成  A ，版本号也不会变回来。

```java title='AtomocStampedReference 的方法签名'
boolean compareAndSet(V expectedReference,V newReference,int expectedStamp,int newStamp)
```

AtomicMarkableReference 的实现机制则更简单，将版本号简化成了一个 Boolean 值，方法签名如下：

```java
boolean compareAndSet(V expectedReference,V newReference,boolean expectedMark,boolean newMark)
```

### 3. 原子化数组

相关实现有 AtomicIntegerArray 、 AtomicLongArray 和 AtomicReferenceArray，利用这些原子类，可以原子化地更新数组里面的每一个元素。这些类提供的方法和原子化的基本类型的区别仅仅在于：每个方法多个一个数组的索引参数。

### 5. 原子化对象属性更新器

